import uuid

import mistune
from django.db.models import Q
from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import api_view, renderer_classes
from rest_framework.response import Response
from rest_framework.status import HTTP_200_OK, HTTP_400_BAD_REQUEST, HTTP_500_INTERNAL_SERVER_ERROR
from rest_framework.utils import json

from .models import Essay, Series, Comment, Label
from .renderers import UTF8JSONRenderer
from .serializers import EssaySerializers, EssayListSerializers, SeriesListSerializers, SeriesSerializers, \
    LabelListSerializers

PAGE_SIZE = 8
headers = {"Access-Control-Allow-Origin": "*"}


@csrf_exempt
@api_view(['GET'])
@renderer_classes([UTF8JSONRenderer])
def essay_list(request, page_size):
    try:
        page_size = int(page_size)
    except TypeError:
        return Response("page_number and page_size must be int", HTTP_400_BAD_REQUEST, headers=headers)
    if page_size < 5:
        page_size = 5
    if request.method == 'GET':
        essays = Essay.objects.all().order_by('-create_time')[:page_size]
        serializer = EssayListSerializers(essays, many=True)
        return Response(serializer.data, status=HTTP_200_OK, headers=headers)


@csrf_exempt
@api_view(['GET'])
@renderer_classes([UTF8JSONRenderer])
def series_list(request, page_size):
    try:
        page_size = int(page_size)
    except TypeError:
        return Response("page_number and page_size must be int", HTTP_400_BAD_REQUEST, headers=headers)
    if page_size < 5:
        page_size = 5
    if request.method == 'GET':
        series = Series.objects.all().order_by('-create_time')[:page_size]
        serializer = SeriesListSerializers(series, many=True)
        return Response(serializer.data, status=HTTP_200_OK, headers=headers)


@csrf_exempt
@api_view(['GET'])
@renderer_classes([UTF8JSONRenderer])
def series_pagination(request, page_number, page_size):
    try:
        page_number = int(page_number)
        page_size = int(page_size)
    except TypeError:
        return Response("page_number and page_size must be int", HTTP_400_BAD_REQUEST, headers=headers)

    if page_size == 0:
        page_size = PAGE_SIZE
    if page_number < 1:
        page_number = 1
    start = (page_number - 1) * page_size
    end = start + page_size
    if request.method == 'GET':
        series = Series.objects.all().order_by('-create_time')[start:end]
        serializer = SeriesListSerializers(series, many=True)
        return Response(serializer.data, status=HTTP_200_OK, headers=headers)


@csrf_exempt
@api_view(['GET'])
@renderer_classes([UTF8JSONRenderer])
def label_pagination(request, page_number, page_size):
    try:
        page_number = int(page_number)
        page_size = int(page_size)
    except TypeError:
        return Response("page_number and page_size must be int", HTTP_400_BAD_REQUEST, headers=headers)

    if page_size == 0:
        page_size = PAGE_SIZE
    if page_number < 1:
        page_number = 1
    start = (page_number - 1) * page_size
    end = start + page_size
    if request.method == 'GET':
        labels = Label.objects.all()[start:end]
        serializer = LabelListSerializers(labels, many=True)
        return Response(serializer.data, status=HTTP_200_OK, headers=headers)


@csrf_exempt
@api_view(['GET'])
@renderer_classes([UTF8JSONRenderer])
def series_detail(request, pk):
    try:
        series = Series.objects.get(pk=pk)
    except Series.DoesNotExist:
        return Response("目标不存在", HTTP_400_BAD_REQUEST, headers=headers)

    if request.method == 'GET':
        serializer = SeriesSerializers(series)
        return Response(serializer.data, status=HTTP_200_OK, headers=headers)
    elif request.method == 'DELETE':
        series.delete()
        return Response(status=HTTP_200_OK, headers=headers)


def build_tree(parent_id, comment_list):
    if parent_id == 'root':
        parent_id = ''
    child_list = []
    value_tree = []
    for comment in comment_list:
        if comment['parent_id'] == parent_id:
            child_list.append(comment)
        # if len(child_list) == 0:
        #     return {}
        # else:
    for child_comment in child_list:
        child_dic = build_tree(child_comment['id'], comment_list)
        if len(child_dic) != 0:
            value_tree.append(child_dic)
    if len(value_tree) == 0:
        return parent_id
    if parent_id == '' or parent_id == 'root':
        dict = {'root': value_tree}
    else:
        dict = {parent_id: value_tree}
    return dict


markdown_html = mistune.Markdown(escape=True, hard_wrap=True)


@csrf_exempt
@api_view(['GET'])
@renderer_classes([UTF8JSONRenderer])
def essay_detail(request, pk):
    try:
        essay = Essay.objects.get(pk=pk)
        if essay.content != '':
            essay.html_content = markdown_html(essay.content)
    except Essay.DoesNotExist:
        return Response("目标不存在", HTTP_400_BAD_REQUEST, headers=headers)

    if request.method == 'GET':
        serializer = EssaySerializers(essay)
        comments = serializer.data['essay_comment']
        serializer._data['tree'] = build_tree('root', comments)
        return Response(serializer.data, status=HTTP_200_OK, headers=headers)
    elif request.method == 'DELETE':
        essay.delete()
        return Response(status=HTTP_200_OK, headers=headers)


@csrf_exempt
@api_view(['GET'])
@renderer_classes([UTF8JSONRenderer])
def essay_pagination(request, page_number, page_size):
    try:
        page_number = int(page_number)
        page_size = int(page_size)
    except TypeError:
        return Response("page_number and page_size must be int", HTTP_400_BAD_REQUEST, headers=headers)

    if page_size == 0:
        page_size = PAGE_SIZE
    start = (page_number - 1) * page_size
    end = start + page_size
    if request.method == 'GET':
        essays = Essay.objects.all().order_by('-create_time')[start:end]
        serializer = EssayListSerializers(essays, many=True)
        return Response(serializer.data, status=HTTP_200_OK, headers=headers)


@csrf_exempt
@api_view(['POST'])
@renderer_classes([UTF8JSONRenderer])
def add_comment(request):
    if request.method == 'POST':
        try:
            params = json.loads(request.body)
            parent_id = params['parent_id']
            nick_name = params['nick_name']
            rich_text = params['rich_text']
            essay_id = params['essay_id']
            comment = Comment(parent_id=parent_id, nick_name=nick_name, rich_text=rich_text,
                              essay_id=essay_id)
            comment.save()
            return Response("success", status=HTTP_200_OK, headers=headers)
        except Exception:
            return Response("error", status=HTTP_500_INTERNAL_SERVER_ERROR, headers=headers)
    else:
        return Response("must be post", HTTP_400_BAD_REQUEST, headers=headers)


@csrf_exempt
@api_view(['GET'])
@renderer_classes([UTF8JSONRenderer])
def search_by_label(request, label_id, page_number, page_size):
    try:
        page_number = int(page_number)
        page_size = int(page_size)
    except TypeError:
        return Response("page_number and page_size must be int", HTTP_400_BAD_REQUEST, headers=headers)
    if page_size < 5:
        page_size = 5
    if page_number < 1:
        page_number = 1
    if request.method == 'GET':
        essays = Essay.objects.filter(labels=label_id).order_by('-create_time')[(page_number - 1) * page_size:page_size]
        serializer = EssayListSerializers(essays, many=True)
        return Response(serializer.data, status=HTTP_200_OK, headers=headers)


@csrf_exempt
@api_view(['GET'])
@renderer_classes([UTF8JSONRenderer])
def search_essay(request, value):
    if request.method == 'GET':
        essays = Essay.objects.filter(Q(title__icontains=value) | Q(summary__icontains=value))
        serializer = EssayListSerializers(essays, many=True)
        return Response(serializer.data, status=HTTP_200_OK, headers=headers)
